import sys
import os
import subprocess
import math
import numpy as np
import statistics
import requests
import time

# 缓存用于存储上一次成功查询的数值，防止在查询失败时导致服务不可用
cached_values = {
    "Available_Replicas": None,
    "Operational_Replicas": None,
    "cpu_request": 100.0,
    "Desired_Replicas": None,
    "current_cpu": None,
}

def query_prometheus(query):
    url = "http://10.10.100.40:30090/api/v1/query"
    params = {'query': query}

    try:
        response = requests.get(url, params=params)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Error querying Prometheus: {e}")
        return None

def Monitor():
    microservice_name = "cartservice"

    # 查询可用副本数
    replica_query = 'kube_deployment_status_replicas_available{namespace="boutique", deployment="cartservice"}'
    available_replicas_result = query_prometheus(replica_query)
    if available_replicas_result and available_replicas_result.get('data', {}).get('result'):
        Available_Replicas = int(available_replicas_result['data']['result'][0]['value'][1])
        cached_values["Available_Replicas"] = Available_Replicas
    else:
        print("Warning: Prometheus query for Available Replicas failed, using cached value.")
        Available_Replicas = cached_values["Available_Replicas"]

    # 查询 CPU 使用率
    cpu_query = 'rate(container_cpu_usage_seconds_total{namespace="boutique", pod=~"cartservice-.*", container="cartservice"}[1m])'
    cpu_usage_result = query_prometheus(cpu_query)
     # 检查并设置 Operational_Replicas
    if cpu_usage_result and isinstance(cpu_usage_result.get('data', {}).get('result'), list):
        cpu_usage_result_data = cpu_usage_result['data']['result']
        Operational_Replicas = len(cpu_usage_result_data)
        cached_values["Operational_Replicas"] = Operational_Replicas
    else:
        print("Warning: Prometheus query for Operational Replicas failed, using cached value.")
        Operational_Replicas = cached_values.get("Operational_Replicas", 0)

    # 设置 current_replicas 为 Available_Replicas
    current_replicas = Available_Replicas

    # 计算当前 CPU 使用率
    cpu_add = []
    if cpu_usage_result and isinstance(cpu_usage_result.get('data', {}).get('result'), list):
        for result in cpu_usage_result['data']['result']:
            if isinstance(result, dict) and 'value' in result:
                try:
                    cpu_usage_value = float(result['value'][1]) * 1000  # 将核转换为毫核
                    cpu_add.append(cpu_usage_value)
                except (TypeError, IndexError, ValueError):
                    print(f"Error: Invalid CPU usage data format for result: {result}")
    else:
        print("Warning: No valid CPU usage data found or Prometheus query failed.")
        cpu_add = [cached_values["current_cpu"]] if cached_values["current_cpu"] is not None else []

    # 计算平均 CPU 使用率
    if cpu_add:
        current_cpu = math.ceil(statistics.mean(cpu_add))
        cached_values["current_cpu"] = current_cpu
        print(f"Average current CPU usage (milliCores): {current_cpu}")
    else:
        print("Warning: No CPU usage data found, using cached value.")
        current_cpu = cached_values.get("current_cpu", 0)

    # 查询期望副本数
    desired_replica_query = 'kube_deployment_spec_replicas{namespace="boutique", deployment="cartservice"}'
    desired_replicas_result = query_prometheus(desired_replica_query)
    if desired_replicas_result and desired_replicas_result.get('data', {}).get('result'):
        Desired_Replicas = int(desired_replicas_result['data']['result'][0]['value'][1])
        cached_values["Desired_Replicas"] = Desired_Replicas
    else:
        print("Warning: Prometheus query for Desired Replicas failed, using cached value.")
        Desired_Replicas = cached_values["Desired_Replicas"]

    # 查询 CPU 请求值
    cpu_request = cached_values["cpu_request"]
    
    # 设置 SLA 指标
    target_cpu = 50
    max_replica = 5
    min_replica = 1

    return microservice_name, Desired_Replicas, current_replicas, current_cpu, target_cpu, cpu_request, max_replica, min_replica

def Analyse(Desired_Replicas, current_replicas, current_cpu, target_cpu, cpu_request, min_replica):
        # 如果 current_cpu 或 cpu_request 为 None，则使用默认值
    current_cpu = current_cpu if current_cpu is not None else 0  # 默认为 0
    cpu_request = cpu_request if cpu_request is not None else 100.0  # 默认为 200.0 毫核
    
    if cpu_request > 0:
        cpu_percentage = (current_cpu / cpu_request) * 100
    else:
        cpu_percentage = 0

    previous_desired_replicas = Desired_Replicas
    desired_replica = math.ceil(int(current_replicas) * (int(cpu_percentage) / int(target_cpu)))

    if (previous_desired_replicas != desired_replica) and (desired_replica > current_replicas) and (desired_replica >= min_replica):
        scaling_action = "scale up"
    elif (previous_desired_replicas != desired_replica) and (desired_replica < current_replicas) and (desired_replica >= min_replica):
        scaling_action = "scale down"
    else:
        scaling_action = "no scale"

    return cpu_percentage, scaling_action, desired_replica
#********************************************************************** Microservice_Main_Function ********************************************************************************

from openpyxl import Workbook, load_workbook

def checkoutservice(Test_Time, folder_name):
    # 获取监控数据
    microservice_name, P_Desired_Replicas, current_replicas, current_cpu, target_cpu, cpu_request, max_replica, min_replica = Monitor()
    cpu_percentage, scaling_action, desired_replica = Analyse(P_Desired_Replicas, current_replicas, current_cpu, target_cpu, cpu_request, min_replica)

    checkoutservice_data = [microservice_name, scaling_action, desired_replica, current_replicas, cpu_request, max_replica]

    # 文件路径
    file_path = f'/root/wmxstudy/Smart_HPA/Smart_HPA_Codebase/Knowledge_Base/{folder_name}/checkoutservice.xlsx'

    # 尝试加载工作簿，若文件不存在则创建一个新文件
    try:
        workbook = load_workbook(file_path)
    except FileNotFoundError:
        print("Workbook not found, creating a new one.")
        workbook = Workbook()
        workbook.save(file_path)
        workbook = load_workbook(file_path)

    sheet = workbook.active

    # 设置表头
    sheet.cell(row=1, column=1, value="Test Time (sec)")
    sheet.cell(row=1, column=2, value="CPU Usage Percentage")
    sheet.cell(row=1, column=3, value="Current Replicas")
    sheet.cell(row=1, column=4, value="Desired Replicas")
    sheet.cell(row=1, column=5, value="Max. Replicas")
    sheet.cell(row=1, column=6, value="Scaling Action")

    # 插入数据
    Test_Time_row_length = len(sheet['A']) + 1
    sheet[f'A{Test_Time_row_length}'] = Test_Time
    sheet[f'B{Test_Time_row_length}'] = cpu_percentage
    sheet[f'C{Test_Time_row_length}'] = current_replicas
    sheet[f'D{Test_Time_row_length}'] = desired_replica
    sheet[f'E{Test_Time_row_length}'] = max_replica
    sheet[f'F{Test_Time_row_length}'] = scaling_action

    # 保存工作簿
    workbook.save(file_path)

    return checkoutservice_data
